import { useCallback, useState } from 'react';

interface RequestOptions {
  onSuccess?: (data: unknown) => void;
  onError?: (error: unknown) => void;
}

interface UseAsyncParams<T, Args extends unknown[] = unknown[]> {
  requestFun: (...args: Args) => Promise<T>;
  options?: RequestOptions;
}

export function useAsync<T, Args extends unknown[] = unknown[]>({
  requestFun,
  options,
}: UseAsyncParams<T, Args>) {
  const [loading, setLoading] = useState(false);

  const run = useCallback(
    async (...args: Args) => {
      if (loading) return;
      try {
        setLoading(true);
        const data = await requestFun(...args);
        options?.onSuccess?.(data);
        return data;
      } catch (error) {
        options?.onError?.(error);
        throw error;
      } finally {
        setLoading(false);
      }
    },
    [loading, requestFun, options]
  );

  return { run, loading };
}
